package com.adds.lvds.security.acegi;

import java.io.IOException;
import java.util.List;

import javax.inject.Inject;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.springframework.security.access.SecurityMetadataSource;
import org.springframework.security.access.intercept.AbstractSecurityInterceptor;
import org.springframework.security.access.intercept.InterceptorStatusToken;
import org.springframework.security.core.session.SessionInformation;
import org.springframework.security.core.session.SessionRegistry;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;

import com.adds.lvds.core.utils.PropertiesUtils;
import com.adds.lvds.security.acegi.session.PmcPrincipal;
import com.adds.lvds.security.acegi.utils.Common;
import com.adds.lvds.security.acegi.utils.CurrentUserUtils;
import com.adds.lvds.security.acegi.utils.MenuUtil;
import com.adds.lvds.security.model.SysCurrentUser;

public class MySecurityFilter extends AbstractSecurityInterceptor implements Filter {
	// 与applicationContext-security.xml里的myFilter的属性securityMetadataSource对应，
	// 其他的两个组件，已经在AbstractSecurityInterceptor定义
	private FilterInvocationSecurityMetadataSource securityMetadataSource;
	@Inject
	private SessionRegistry sessionRegistry;

	@Override
	public SecurityMetadataSource obtainSecurityMetadataSource() {
		return this.securityMetadataSource;
	}

	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {

		FilterInvocation fi = new FilterInvocation(request, response, chain);
		String url = fi.getFullRequestUrl();
		// 判断session是否过期

		List<Object> userList = sessionRegistry.getAllPrincipals();
		for (int i = 0; i < userList.size(); i++) {
			PmcPrincipal userTemp = (PmcPrincipal) userList.get(i);
			if (userTemp.getUsername().equals(CurrentUserUtils.getUsername())) {
				List<SessionInformation> list = sessionRegistry.getAllSessions(userTemp, false);
				if (list.isEmpty()) {
					fi.getResponse().sendRedirect(
							fi.getRequest().getSession().getServletContext().getContextPath() + "/sessionTimeout");
				} else {

				}
			}
		}
		if (StringUtils.isEmpty(CurrentUserUtils.getUsername())) {
			fi.getResponse().sendRedirect(fi.getRequest().getSession().getServletContext().getContextPath() + "/login");
		} else if (!url.endsWith(".do") ||!url.endsWith(".action") || url.endsWith(".html")) {
			invoke(fi);
		} else {
			fi.getResponse().sendRedirect(fi.getRequest().getSession().getServletContext().getContextPath() + "/403");
		}
	}

	private void invoke(FilterInvocation fi) throws IOException, ServletException {
		InterceptorStatusToken token = null;
		token = super.beforeInvocation(fi);
		try {
			fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
		} finally {
			super.afterInvocation(token, null);
		}
	}

	/**
	 * 设置菜单下按钮
	 * 
	 * @param request
	 */
	@SuppressWarnings("unused")
	private void setHtmlBut(FilterInvocation fi) {
		String htmlBut = "";
		if (PropertiesUtils.findPropertiesKey("rootName").equals(Common.findAuthenticatedUsername())) {
			htmlBut = MenuUtil.getMenuChildBut(null, fi.getRequestUrl());
		} else {
			SysCurrentUser sysCurrentUser = CurrentUserUtils.currentUser(fi.getRequest());
			if (sysCurrentUser != null) {
				htmlBut = MenuUtil.getMenuChildBut(sysCurrentUser.getRoleList(), fi.getRequestUrl());
			}
		}

		fi.getRequest().setAttribute("htmlBut", htmlBut);
	}

	public FilterInvocationSecurityMetadataSource getSecurityMetadataSource() {
		return securityMetadataSource;
	}

	public void setSecurityMetadataSource(FilterInvocationSecurityMetadataSource securityMetadataSource) {
		this.securityMetadataSource = securityMetadataSource;
	}

	public void init(FilterConfig arg0) throws ServletException {

	}

	public void destroy() {

	}

	@Override
	public Class<? extends Object> getSecureObjectClass() {
		// 下面的MyAccessDecisionManager的supports方面必须放回true,否则会提醒类型错误
		return FilterInvocation.class;
	}
}